#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <assert.h>

#include "tcpa_monitor.h"
#include "tcpa_util.h"

void test_decode_input_parameter_happy_path() {
    tcpa_monitor_t *tcpam = tcpa_monitor_create();
    char *argv[] = { "program", "--tcpa_cfg_path", "/path/to/tcpa_cfg", "--whitelist_path", "/path/to/whitelist_cfg" };
    int argc = 5;

    decode_input_parameter(argc, argv, tcpam);

    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[TCPA_CFG].file_path, "/path/to/tcpa_cfg") == 0);
    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[WHITELIST_CFG].file_path, "/path/to/whitelist_cfg") == 0);

    tcpa_monitor_destroy(tcpam);
}

void test_decode_input_parameter_missing_tcpa_cfg_path() {
    tcpa_monitor_t *tcpam = tcpa_monitor_create();
    char *argv[] = { "program", "--whitelist_path", "/path/to/whitelist_cfg" };
    int argc = 3;

    decode_input_parameter(argc, argv, tcpam);

    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[TCPA_CFG].file_path, "") == 0);
    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[WHITELIST_CFG].file_path, "/path/to/whitelist_cfg") == 0);

    tcpa_monitor_destroy(tcpam);
}

void test_decode_input_parameter_missing_whitelist_path() {
    tcpa_monitor_t *tcpam = tcpa_monitor_create();
    char *argv[] = { "program", "--tcpa_cfg_path", "/path/to/tcpa_cfg" };
    int argc = 3;

    decode_input_parameter(argc, argv, tcpam);

    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[TCPA_CFG].file_path, "/path/to/tcpa_cfg") == 0);
    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[WHITELIST_CFG].file_path, "") == 0);

    tcpa_monitor_destroy(tcpam);
}

void test_decode_input_parameter_help() {
    tcpa_monitor_t *tcpam = tcpa_monitor_create();
    char *argv[] = { "program", "--help" };
    int argc = 2;

    decode_input_parameter(argc, argv, tcpam);

    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[TCPA_CFG].file_path, "") == 0);
    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[WHITELIST_CFG].file_path, "") == 0);

    tcpa_monitor_destroy(tcpam);
}

void test_decode_input_parameter_unknown_parameter() {
    tcpa_monitor_t *tcpam = tcpa_monitor_create();
    char *argv[] = { "program", "--unknown_parameter" };
    int argc = 2;

    decode_input_parameter(argc, argv, tcpam);

    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[TCPA_CFG].file_path, "") == 0);
    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[WHITELIST_CFG].file_path, "") == 0);

    tcpa_monitor_destroy(tcpam);
}

void test_decode_input_parameter_path_too_long() {
    tcpa_monitor_t *tcpam = tcpa_monitor_create();
    char long_path[256];
    memset(long_path, 'a', 255);
    long_path[255] = '\0';
    char *argv[] = { "program", "--tcpa_cfg_path", long_path };
    int argc = 3;

    decode_input_parameter(argc, argv, tcpam);

    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[TCPA_CFG].file_path, "") == 0);
    assert(strcmp(tcpam->tcpam_cfg_file_ctx.tcpa_cfg_file[WHITELIST_CFG].file_path, "") == 0);

    tcpa_monitor_destroy(tcpam);
}

int main() {
    test_decode_input_parameter_happy_path();
    test_decode_input_parameter_missing_tcpa_cfg_path();
    test_decode_input_parameter_missing_whitelist_path();
    test_decode_input_parameter_help();
    test_decode_input_parameter_unknown_parameter();
    test_decode_input_parameter_path_too_long();

    printf("All tests passed!\n");
    return 0;
}